#include "httpsclient.hpp"

#include "topconn_error.hpp"
#include "topconn_logutil.hpp"

#include "protocal/http/httplib.h"

namespace topconn
{
	HttpsClient::HttpsClient()
		: HttpClient()
		, m_isVerify(false)
	{
	}

	HttpsClient::HttpsClient(const string& url)
		: m_httpsClientPtr(nullptr)
		, HttpClient(url)
		, m_isVerify(false)
	{
	}

	HttpsClient::~HttpsClient()
	{
	}

	void HttpsClient::setCaCertPath(const string& certPath)
	{
		m_caCertPath = certPath;
	}

	void HttpsClient::setCertificateVerify(bool on)
	{
		m_isVerify = on;
	}

	const string& HttpsClient::getCaCertPath()const
	{
		return m_caCertPath;
	}

	bool HttpsClient::isCertificateVerify()const
	{
		return m_isVerify;
	}

	int  HttpsClient::initClient()
	{
		if (!m_httpsClientPtr)
		{
			m_httpsClientPtr = std::make_shared<httplib::SSLClient>(m_url);
			m_httpsClientPtr->set_connection_timeout(m_maxConnTimeout, 0);
			m_httpsClientPtr->set_read_timeout(m_maxRecvTimeout, 0);
			m_httpsClientPtr->set_ca_cert_path(m_caCertPath);

			if (m_isIpv6)
				m_httpsClientPtr->set_address_family(AF_INET6);

			if (m_isKeepalive)
				m_httpsClientPtr->set_keep_alive(m_isKeepalive);

			if (!m_username.empty())
				m_httpsClientPtr->set_proxy_digest_auth(m_username, m_password);

			if (m_isVerify)
				m_httpsClientPtr->enable_server_certificate_verification(m_isVerify);
		}
		return 0;
	}

	int HttpsClient::request(const string& method, const string& path, const string& body, const string& content_type, string& response)
	{
		int iRet = 0;
		httplib::Error error;

		if (!m_httpsClientPtr)
		{
			return INVALID_HANDLE;
		}

		if (method == "post")
		{
			httplib::Result result = m_httpsClientPtr->Post(path, body, content_type);
			error = result.error();
			if (error == httplib::Error::Success)
			{
				response = result->body;
				return SUCESSED;
			}
		}
		else if (method == "get")
		{
			httplib::Result result = m_httpsClientPtr->Get(path);
			error = result.error();
			if (result.error() == httplib::Error::Success)
			{
				response = result->body;
				return SUCESSED;
			}
		}
		else if (method == "put")
		{
			httplib::Result result = m_httpsClientPtr->Put(path, body, content_type);
			error = result.error();
			if (result.error() == httplib::Error::Success)
			{
				response = result->body;
				return SUCESSED;
			}
		}
		else if (method == "delete")
		{
			httplib::Result result = m_httpsClientPtr->Delete(path);
			error = result.error();
			if (result.error() == httplib::Error::Success)
			{
				response = result->body;
				return SUCESSED;
			}
		}
		TLOG_ERROR("method=[%s] error=[%d]", method.c_str(), error);
		if (error == httplib::Error::Connection)
			return CONNECT_ERROR;
		else if (error == httplib::Error::ConnectionTimeout)
			return CONNECT_TIMEOUT;
		else if (error == httplib::Error::Write)
			return SEND_ERROR;
		else if (error == httplib::Error::Read)
			return RECV_ERROR;
		else if (error == httplib::Error::SSLConnection)
			return SSL_CONNECT_ERROR;
		else if (error == httplib::Error::SSLLoadingCerts)
			return SSL_LOAD_CERT_ERROR;
		return OTHER_ERROR;
	}
};